module alu (a, b, op, out, over, carry);
  input [3:0] a;
  input [3:0] b;
  input [2:0] op;
  output reg [3:0] out;
  output reg over;
  output reg carry;

  wire [3:0] neg_b;

  assign neg_b = (~b) + 1;

  always @(op)
    case (op)
      3'b000 :
      begin
        {carry, out} = a + b;
        over = (a[3] == b[3]) && (out[3] != a[3]);
      end
      3'b001 :
      begin
        {carry, out} = a + neg_b;
        over = (a[3] == neg_b[3]) && (out[3] != a[3]);
      end
      3'b010 : out = ~a;
      3'b011 : out = a & b;
      3'b100 : out = a | b;
      3'b101 : out = a ^ b;
      3'b110 :
      begin
        if (a < b) out = 1;
        else out = 0;
      end
      3'b111 :
      begin
        if (a == b) out = 1;
        else out = 0;
      end
      default :
      begin
        out = 0;
        over = 0;
        carry = 0;
      end
    endcase

endmodule
